<?php

namespace app\common\model\fp;


use app\common\model\User;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;
use think\Model;
use think\model\concern\SoftDelete;
use Throwable;

/**
 * 动态模型
 */
class Post extends Model
{
    use SoftDelete;

    protected string $deleteTime = 'delete_time';

    protected $defaultSoftDelete = 0;

    protected $autoWriteTimestamp = true;

    // 默认表名
    protected $name = 'fp_posts';

    const TABLE_NUM = 10;

    protected $type = [
        'id' => 'string',
    ];

    public function getIdAttr($value): string
    {
        return (string)$value;
    }

    protected static function onBeforeInsert($model): void
    {
        $pk = $model->getPk();
        $model->$pk = \app\common\library\SnowFlake::generateParticle();
    }

    // 定义与用户的关系
    public function user(): \think\model\relation\BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id', 'user_id');
    }
    
    /**
     * 如果表不存在，则创建新表
     *
     * @param $tableName
     * @return bool
     * @throws Throwable 如果创建表失败，抛出异常
     */
    public static function createTableIfNotExists($tableName): bool
    {
        $cacheKey = 'makeTable:' . $tableName;
        $check = Cache::get($cacheKey);
        if ($check) {
            return true;
        }
        // 检查表是否存在
        $exists = Db::query("SHOW TABLES LIKE  '{$tableName}'");

        if (!$exists) {
            $sql = <<<SQL
            CREATE TABLE `{$tableName}` (
                  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '动态ID',
                  `title` varchar(255) NOT NULL DEFAULT '' COMMENT '标题，视频的时候才有',
                  `type` enum('0','1') NOT NULL DEFAULT '0' COMMENT '类型：0普通  1精选',
                  `user_id` bigint(20) unsigned NOT NULL COMMENT '用户ID',
                  `repost_id` bigint(20) unsigned DEFAULT '0' COMMENT '转发ID',
                  `content` text NOT NULL COMMENT '动态内容',
                  `payment_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '支付方式：1免费 2金币 3付费',
                  `price` int(11) unsigned DEFAULT '0' COMMENT '查看金额：最小单位（个、分）',
                  `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '审核：0待审核，1审核通过，2审核不通过',
                  `visibility` tinyint(1) NOT NULL DEFAULT '1' COMMENT '可见性：1公开，2仅自己可见，3仅自己和关注用户可见',
                  `show` tinyint(1) NOT NULL DEFAULT '1' COMMENT '展示：0不显示，1显示， 管理员操作',
                  `like_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '点赞数',
                  `is_vip_unlock` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否支持平台会员解锁',
                  `create_time` bigint(16) unsigned DEFAULT NULL COMMENT '发布时间',
                  `update_time` bigint(16) unsigned DEFAULT NULL COMMENT '更新时间',
                  `delete_time` bigint(16) unsigned DEFAULT '0' COMMENT '删除时间',
                  PRIMARY KEY (`id`) USING BTREE,
                  KEY `user_id` (`user_id`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='朋友圈-动态表';
        SQL;

            try {
                Db::execute($sql);
            } catch (Throwable $e) {
                // 记录异常信息
                Log::channel('my')->error("Failed to create table {$tableName}: " . $e->getMessage());
                // 可以选择抛出异常或返回错误信息
                throw new \RuntimeException("Failed to create table: " . $e->getMessage(), 0, $e);
            }
        }

        //创建表
        Cache::set($cacheKey, 1);
        return true;
    }

    /**
     * 实例化表
     * @param $userId
     * @return Post
     * @throws Throwable
     */
    public static function initModel($userId): static
    {
        $model = new static();
        $tableName = 'fp_posts_' . ($userId % self::TABLE_NUM);
        $model->setName($tableName);

        $prefix = config('database.connections.mysql.prefix');
        //创建表
        $model->createTableIfNotExists($prefix . $tableName);

        return $model;
    }

    /**
     * 初始化分表表名
     * @param $userId
     */
    public static function initTable($userId)
    {
        $tableName = 'fp_posts_' . ($userId % self::TABLE_NUM);
        $prefix = config('database.connections.mysql.prefix');
        $tableName = $prefix . $tableName;

        //创建表
        self::createTableIfNotExists($tableName);

        return Db::table($tableName);
    }

    /**
     * 获取分表表名
     * @param $userId
     * @return string
     */
    public static function getDbTableName($userId, $hasPrefix = true): string
    {
        $tableName = 'fp_posts_' . ($userId % self::TABLE_NUM);
        $prefix = '';
        if ($hasPrefix) {
            $prefix = config('database.connections.mysql.prefix');
        }
        return $prefix . $tableName;
    }
}
